package tools;

import controller.Controller;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.io.Serializable;
import model.Model_Config;
import org.jgap.*;
import org.jgap.data.*;
import org.jgap.xml.*;
import org.w3c.dom.*;

/**
 * Hier werden alle attribute gespeichert, die spaeter gespeichert werden muessen
 * Mit hilfe der getter methoden greift der benutzer auf die gespeicherten dateien wieder zu
 */
public class Data implements Serializable {

    private SerializableBufferedImage serializable_image_original, maske;
    private SerializableBufferedImage serializable_image_line;
    private Model_Config config;
    private transient Document xml;
    private java.io.File file;

    /**
     * entnimmt alle Daten zum Speichern.
     * 
     * Daten sind:
     * Model_Config config; BufferedImage image_original;
     * BufferedImage image_line(getFittestImage); Genotype genotype,
     *
     * @throws Exception
     */
    public Data(String path) throws Exception{
        String name = path.substring(0, path.length()-3);
        this.file = new java.io.File(name+"xml");
        setConfig();

        setImage_Original(Controller.getInstance().getImage_original().getImage_original());
        setMaske(Controller.getInstance().getImage_original().getMaske());

        setImage_Line(Controller.getInstance().getImage_Line().getFittestImage());
        // speichern des genotypes
        xml = saveGenotypeInXML(Controller.getInstance().getImage_Line().getGenotype());
        XMLManager.writeFile(xml, this.file);
    }

    private void setConfig(){
        config = Controller.getInstance().getConfig();
    }

    private void setImage_Original(BufferedImage img) {
        this.serializable_image_original = new SerializableBufferedImage(img);
    }

    private void setMaske(BufferedImage maske){
        this.maske = new SerializableBufferedImage(maske);
    }

    private void setImage_Line(BufferedImage img) {
        this.serializable_image_line = new SerializableBufferedImage(img);
    }

    /**
     * erzeugt ein Document xml in dem es Genotyp gespeichert wird
     * @param genotype
     * @return
     */
    private Document saveGenotypeInXML(Genotype genotype) throws Exception {
            DataTreeBuilder builder = DataTreeBuilder.getInstance();
            IDataCreators doc2 = builder.representGenotypeAsDocument(genotype);

            XMLDocumentBuilder docbuilder = new XMLDocumentBuilder();

            Document xmlDoc = (Document) docbuilder.buildDocument(doc2);
            return xmlDoc;
    }

    public BufferedImage getBufferedImage_original() throws Exception {
        return serializable_image_original.getBufferedImage();
    }

    public BufferedImage getMaske() throws Exception{
        return maske.getBufferedImage();
    }

    public BufferedImage getBufferedImage_line() throws Exception {
        return serializable_image_line.getBufferedImage();
    }

    /**
     * Die ausgefuehrte Configuration wird mit den neuen werten
     * imagesPerGeneration, linesPerImage
     * veraendert und ausgegeben.
     * @return config
     */
    public Model_Config getConfig() {
        return this.config;
    }

    /**
     * entnimmt den Genotyp aus Document xml und gibt es zurück
     * @return genotype
     * @throws Exception
     */
    public Genotype getGenotype(String path) throws Exception {
      Controller.getInstance().getImage_Line().newEvolution();
      Configuration genoConf = Controller.getInstance().getImage_Line().getGenoConf();
        /**
         * genotype einlesen
         */
      Genotype genotype = XMLManager.getGenotypeFromDocument(genoConf, XMLManager.readFile(new File(path)));
      return genotype;
    }
}